package com.ljh.onlinetest.service.impl;

/**
 * @author 余一
 * @date 2022/2/15  22:27
 */

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ljh.onlinetest.domain.ExamPaper;
import com.ljh.onlinetest.domain.TaskExam;
import com.ljh.onlinetest.domain.TextContent;
import com.ljh.onlinetest.domain.User;
import com.ljh.onlinetest.domain.task.TaskItemObject;
import com.ljh.onlinetest.repository.BaseMapper;
import com.ljh.onlinetest.repository.ExamPaperMapper;
import com.ljh.onlinetest.repository.TaskExamMapper;
import com.ljh.onlinetest.service.TaskExamService;
import com.ljh.onlinetest.service.TextContentService;
import com.ljh.onlinetest.service.enums.ActionEnum;
import com.ljh.onlinetest.utils.DateTimeUtil;
import com.ljh.onlinetest.utils.JsonUtil;
import com.ljh.onlinetest.utils.ModelMapperSingle;
import com.ljh.onlinetest.viewmodel.admin.paper.PaperResponseVM;
import com.ljh.onlinetest.viewmodel.admin.task.TaskPageRequestVM;
import com.ljh.onlinetest.viewmodel.admin.task.TaskRequestVM;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class TaskExamServiceImpl extends BaseServiceImpl<TaskExam> implements TaskExamService{

    protected final static ModelMapper modelMapper = ModelMapperSingle.Instance();
    private final TaskExamMapper taskExamMapper;
    private final TextContentService textContentService;
    private final ExamPaperMapper examPaperMapper;

    @Autowired
    public TaskExamServiceImpl(TaskExamMapper taskExamMapper,TextContentService textContentService,ExamPaperMapper examPaperMapper) {
        super(taskExamMapper);
        this.taskExamMapper = taskExamMapper;
        this.textContentService = textContentService;
        this.examPaperMapper = examPaperMapper;
    }

    @Override
    public PageInfo<TaskExam> page(TaskPageRequestVM requestVM) {
        return PageHelper.startPage(requestVM.getPageIndex(),requestVM.getPageSize(),"id desc").doSelectPageInfo(() -> {
            taskExamMapper.page(requestVM);
        });
    }

    @Override
    public TaskRequestVM taskExamToVM(Integer id) {
        TaskExam taskExam = taskExamMapper.selectByPrimaryKey(id);
        TaskRequestVM requestVM = modelMapper.map(taskExam, TaskRequestVM.class);
        TextContent textContent = textContentService.selectById(taskExam.getFrameTextContentId());
        List<PaperResponseVM> paperItems = JsonUtil.toJsonListObject(textContent.getContent(), TaskItemObject.class).stream().map(tk -> {
            ExamPaper examPaper = examPaperMapper.selectByPrimaryKey(tk.getExamPaperId());
            PaperResponseVM paperResponseVM = modelMapper.map(examPaper, PaperResponseVM.class);
            paperResponseVM.setCreateTime(DateTimeUtil.dateFormat(examPaper.getCreateTime()));
            return paperResponseVM;
        }).collect(Collectors.toList());
        requestVM.setPaperItems(paperItems);
        return requestVM;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(TaskRequestVM model, User currentUser) {
        ActionEnum actionEnum = model.getId() == null ? ActionEnum.ADD : ActionEnum.UPDATE;
        TaskExam taskExam = null;
        if (actionEnum == ActionEnum.ADD) {
            Date now = new Date();
            taskExam = modelMapper.map(model, TaskExam.class);
            taskExam.setCreateUser(currentUser.getId());
            taskExam.setCreateUserName(currentUser.getUserName());
            taskExam.setCreateTime(now);
            taskExam.setDeleted(false);

            TextContent textContent = textContentService.jsonConvertInsert(model.getPaperItems(), now, p -> {
                TaskItemObject taskItemObject = new TaskItemObject();
                taskItemObject.setExamPaperId(p.getId());
                taskItemObject.setExamPaperName(p.getName());
                return taskItemObject;
            });
            //添加任务试卷内容
            textContentService.insertByFilter(textContent);
            taskExam.setFrameTextContentId(textContent.getId());
            //添加任务
            taskExamMapper.insertSelective(taskExam);
        } else {
            taskExam = taskExamMapper.selectByPrimaryKey(model.getId());
            //将修改的信息更新到model
            modelMapper.map(model,taskExam);

            TextContent textContent = textContentService.selectById(taskExam.getFrameTextContentId());
            //清空任务试卷的id，后面再统一设置
            List<Integer> examPaperIds = JsonUtil.toJsonListObject(textContent.getContent(), TaskItemObject.class)
                    .stream()
                    .map(d -> d.getExamPaperId())
                    .collect(Collectors.toList());
            examPaperMapper.clearTaskPaper(examPaperIds);

            //更新任务结构
            textContentService.jsonConvertUpdate(textContent,model.getPaperItems(),q -> {
                TaskItemObject taskItemObject = new TaskItemObject();
                taskItemObject.setExamPaperId(q.getId());
                taskItemObject.setExamPaperName(q.getName());
                return taskItemObject;
            });
            textContentService.updateByIdFilter(textContent);
            taskExamMapper.updateByPrimaryKeySelective(taskExam);
        }
        //更新试卷的taskId
        List<Integer> paperIds = model.getPaperItems().stream().map(d -> d.getId()).collect(Collectors.toList());
        examPaperMapper.updateTaskPaper(taskExam.getId(),paperIds);
        model.setId(taskExam.getId());
    }

    @Override
    public List<TaskExam> getByGradeLevel(Integer userLevel) {
        return taskExamMapper.getByGradeLevel(userLevel);
    }

    @Override
    @Transactional
    public int deleteById(Integer id) {
        TaskExam taskExam = selectById(id);
        taskExam.setDeleted(true);
        TextContent textContent = textContentService.selectById(taskExam.getFrameTextContentId());
        //清空任务试卷的id
        List<Integer> examPaperIds = JsonUtil.toJsonListObject(textContent.getContent(), TaskItemObject.class)
                .stream()
                .map(d -> d.getExamPaperId())
                .collect(Collectors.toList());
        examPaperMapper.clearTaskPaper(examPaperIds);
        return updateByIdFilter(taskExam);
    }
}
